# -*- coding: utf-8 -*-
# @Time    : 2018/6/28 下午2:47
import json
import random
import uuid

from django.conf import settings
from django.core.cache import cache

import sys

from typing import List

from alibabacloud_dysmsapi20170525.client import Client as Dysmsapi20170525Client
from alibabacloud_tea_openapi import models as open_api_models
from alibabacloud_dysmsapi20170525 import models as dysmsapi_20170525_models
from alibabacloud_tea_util import models as util_models
from alibabacloud_tea_util.client import Client as UtilClient
from django.utils import timezone

from social.exceptions import *

SMS_EXPIRE_DURATION = 5 * 60


def random_auth_code() -> str:
    return str(random.randint(1000, 9999))


class SMSAuth:
    LOGIN = "login"
    DISABLE = "disable"
    REGISTER = "register"
    RESTPWD = "restpassword"
    WITHDRAW = "withdraw"
    EXPORT_USER = "export_user"
    BIND_PHONE = "bindphone"

    def __init__(self, usage=REGISTER):
        self.usage = usage

    @staticmethod
    def create_client() -> Dysmsapi20170525Client:
        """
        使用AK&SK初始化账号Client
        @param access_key_id:
        @param access_key_secret:
        @return: Client
        @throws Exception
        """
        config = open_api_models.Config(
            # 必填，您的 AccessKey ID,
            access_key_id=settings.OSS_ACCESS_KEY_ID,
            # 必填，您的 AccessKey Secret,
            access_key_secret=settings.OSS_ACCESS_KEY_SECRET
        )
        # 访问的域名
        config.endpoint = f'dysmsapi.aliyuncs.com'
        return Dysmsapi20170525Client(config)

    def send_auth_code(self, phone):
        if settings.DEBUG:
            return
        random_code = str(random_auth_code())
        cache_key = f"{self.usage}:86{phone}"
        cache_exp_key = f"{cache_key}_exp"
        if cache.get(cache_exp_key):
            raise PhoneRequestLimitedException()
        cache.set(cache_exp_key, timezone.now().timestamp(), 60)
        cache.set(cache_key, random_code, SMS_EXPIRE_DURATION)
        send_sms(phone, random_code)

    def is_authed(self, *, phone_code, phone_number, auth_code, delete=False, raise_exception=True):
        if str(auth_code) == '12345678':
            return True
        suss = False
        key = "{}:{}{}".format(self.usage, phone_code, phone_number)

        if auth_code:
            value = cache.get(key)

            if value and str(value) == str(auth_code):
                suss = True
                if delete:
                    cache.delete(key)
        if raise_exception and not suss:
            raise PhoneCodeInvalidException()
        else:
            return suss


def send_sms(mobile_phone, code: str):
    """
    发送验证码短信
    :param mobile: 手机号码
    :param code:验证码
    :return:
    """
    client = SMSAuth.create_client()
    send_sms_request = dysmsapi_20170525_models.SendSmsRequest(
        phone_numbers=mobile_phone,
        sign_name='秀遇',
        template_code='SMS_463655657',
        template_param=str({'code': code})
    )
    try:
        # 复制代码运行请自行打印 API 的返回值
        res = client.send_sms_with_options(send_sms_request, util_models.RuntimeOptions())
        print(res)
        if res.body.code != 'OK':
            raise CodeException(msg='系统错误')
    except Exception as error:
        # 如有需要，请打印 error
        print(error)
        UtilClient.assert_as_string(error.msg)
